﻿using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

// The Search Contract item template is documented at http://go.microsoft.com/fwlink/?LinkId=234240

namespace MetroContractSample
{
  /// <summary>
  /// This page displays search results when a global search is directed to this application.
  /// </summary>
  public sealed partial class SearchResultsPage : MetroContractSample.Common.LayoutAwarePage
  {
    /// <summary>
    /// Records the value of the active Window's Content property when the search started.
    /// </summary>
    private UIElement _previousContent;

    public SearchResultsPage()
    {
      this.InitializeComponent();
    }

    /// <summary>
    /// Records the value of the active Window's Content property when the search started.
    /// </summary>
    public static void Activate(String queryText)
    {
      // If the Window isn't already using Frame navigation, insert our own Frame
      var previousContent = Window.Current.Content;
      var frame = previousContent as Frame;

      if (frame.Content.GetType() == typeof(BlankPage))
      {
        // BlankPage から来たときは、戻さない
        previousContent = null;
        frame = null;
      }

      if (frame == null)
      {
        frame = new Frame();
        Window.Current.Content = frame;
      }

      // Use navigation to display the results, packing both the query text and the previous
      // Window content into a single parameter object
      frame.Navigate(typeof(SearchResultsPage),
          new Tuple<String, UIElement>(queryText, previousContent));
      Window.Current.Activate();
    }

    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.  The
    /// Parameter property provides the collection of items to be displayed.</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
      // Unpack the two values passed in the parameter object: query text and previous
      // Window content
      var parameter = (Tuple<String, UIElement>)e.Parameter;
      var queryText = parameter.Item1;
      this._previousContent = parameter.Item2;

      // TODO: Application-specific searching logic.  The seach process is responsible for
      //       creating a list of user-selectable result categories:
      //
      //       filterList.Add(new Filter("<filter name>", <result count>));
      //
      //       Only the first filter, typically "All", should pass true as a third argument in
      //       order to start in an active state.  Results for the active filter are provided
      //       in Filter_SelectionChanged below.

      var filterList = new List<Filter>();
      filterList.Add(new Filter("All", 0, true));

      // Communicate results through the view model
      this.DefaultViewModel["QueryText"] = '\u201c' + queryText + '\u201d';
      this.DefaultViewModel["CanGoBack"] = this._previousContent != null;
      this.DefaultViewModel["Filters"] = filterList;
      this.DefaultViewModel["ShowFilters"] = filterList.Count > 1;


      // 絞り込み結果をバインド
      var filterd = App.DataSource.FilteredByFilename(queryText).ToList();
      filterd.Sort();
      this.DefaultViewModel["Results"] = filterd;
    }

    /// <summary>
    /// Invoked when the back button is pressed.
    /// </summary>
    /// <param name="sender">The Button instance representing the back button.</param>
    /// <param name="e">Event data describing how the button was clicked.</param>
    protected override void GoBack(object sender, RoutedEventArgs e)
    {
      // Return the application to the state it was in before search results were requested
      var frame = this._previousContent as Frame;
      if (frame != null && frame.CanGoBack)
      {
        frame.GoBack();
      }
      else
      {
        if (this._previousContent != null)
        {
          Window.Current.Content = this._previousContent;
        }
        else
        {
          var rootFrame = new Frame();
          rootFrame.Navigate(typeof(GroupedItemsPage));//, sampleData.ItemGroups);
          Window.Current.Content = rootFrame;
          Window.Current.Activate();
        }
      }
    }

    /// <summary>
    /// Invoked when a filter is selected using the ComboBox in snapped view state.
    /// </summary>
    /// <param name="sender">The ComboBox instance.</param>
    /// <param name="e">Event data describing how the selected filter was changed.</param>
    void Filter_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
      // Determine what filter was selected
      var selectedFilter = e.AddedItems.FirstOrDefault() as Filter;
      if (selectedFilter != null)
      {
        // Mirror the results into the corresponding Filter object to allow the
        // RadioButton representation used when not snapped to reflect the change
        selectedFilter.Active = true;

        // TODO: Respond to the change in active filter by setting this.DefaultViewModel["Results"]
        //       to a collection of items with bindable Image, Title, and Subtitle properties
      }
    }

    /// <summary>
    /// Invoked when a filter is selected using a RadioButton when not snapped.
    /// </summary>
    /// <param name="sender">The selected RadioButton instance.</param>
    /// <param name="e">Event data describing how the RadioButton was selected.</param>
    void Filter_Checked(object sender, RoutedEventArgs e)
    {
      // Mirror the change into the CollectionViewSource used by the corresponding ComboBox
      // to ensure that the change is reflected when snapped
      if (filtersViewSource.View != null)
      {
        var filter = (sender as FrameworkElement).DataContext;
        filtersViewSource.View.MoveCurrentTo(filter);
      }
    }

    /// <summary>
    /// View model describing one of the filters available for viewing search results.
    /// </summary>
    private sealed class Filter : MetroContractSample.Common.BindableBase
    {
      private String _name;
      private int _count;
      private bool _active;

      public Filter(String name, int count, bool active = false)
      {
        this.Name = name;
        this.Count = count;
        this.Active = active;
      }

      public override String ToString()
      {
        return Description;
      }

      public String Name
      {
        get { return _name; }
        set { if (this.SetProperty(ref _name, value)) this.OnPropertyChanged("Description"); }
      }

      public int Count
      {
        get { return _count; }
        set { if (this.SetProperty(ref _count, value)) this.OnPropertyChanged("Description"); }
      }

      public bool Active
      {
        get { return _active; }
        set { this.SetProperty(ref _active, value); }
      }

      public String Description
      {
        get { return String.Format("{0} ({1})", _name, _count); }
      }
    }
  }
}
